package main

import (
	"database/sql"
	"encoding/json"
	"fmt"
	"net/http"
	"strconv"
	"time"
)

const (
	Expire = 24 * 60 * 60
)

func JsonReturn(w http.ResponseWriter, code int, data interface{}) error {
	r := make(map[string]interface{})
	r["code"] = code
	r["info"] = ErrorInfo[code]
	r["data"] = data
	b, err := json.Marshal(r)
	if err != nil {
		return err
	}
	_, err = w.Write(b)
	if err != nil {
		return err
	}
	return nil
}

func Auth(w http.ResponseWriter, r *http.Request) {
	Code, Gid := r.FormValue("code"), r.FormValue("gid")
	if Code == "" || Gid == "" {
		JsonReturn(w, Err_InvalidParameter, nil)
		return
	}

	iGid, err := strconv.Atoi(Gid)
	if err != nil {
		JsonReturn(w, Err_InvalidParameter, nil)
		return
	}

	if err := VerifyCode(r.Form); err != nil {
		JsonReturn(w, Err_VerifyFailure, nil)
		return
	}

	data := make(map[string]interface{})

	info, err := QueryCode(Code)
	if err != nil {
		if err == sql.ErrNoRows {
			uid, err := InsertCode(Code)
			if err != nil {
				JsonReturn(w, Err_ServerError, nil)
				logger.Error("Insert Failed:", err)
				return
			}
			info.Uid = int(uid)
		} else {
			JsonReturn(w, Err_ServerError, nil)
			logger.Error("Query Failed:", err)
			return
		}
	}

	sess := &Session{}
	sess.Uid = uint32(info.Uid)
	sess.Gid = uint32(iGid)
	sess.Expire = Expire
	sess.Timestamp = uint32(time.Now().Unix())

	var token []byte
	if token, err = sess.Encryp(); err != nil {
		JsonReturn(w, Err_ServerError, nil)
		logger.Error("Session Encrpy Failed:", err)
		return
	}

	data["gid"] = sess.Gid
	data["uid"] = sess.Uid
	data["token"] = fmt.Sprintf("%x", token)

	logger.Info("Auth Success|GID:%d|UID:%d|TOKEN:%s", sess.Gid, sess.Uid, data["token"])

	JsonReturn(w, Err_Success, data)
}
